package com.lej.core.utils

import android.graphics.PointF
import android.view.View
import android.view.ViewGroup
import com.lxj.xpopup.animator.PopupAnimator
import com.lxj.xpopup.core.*
import com.lxj.xpopup.enums.PopupAnimation
import com.lxj.xpopup.enums.PopupPosition
import com.lxj.xpopup.enums.PopupType
import com.lxj.xpopup.interfaces.XPopupCallback
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.concurrent.ConcurrentLinkedQueue

fun <T : BasePopupView> T.build(
    isDismissOnBackPressed: Boolean? = true //按返回键是否消失
    , isDismissOnTouchOutside: Boolean? = true //点击外部消失
    , autoDismiss: Boolean? = true //操作完毕后是否自动关闭
    , hasShadowBg: Boolean? = true // 是否有半透明的背景
    , hasBlurBg: Boolean? = false // 是否有高斯模糊背景
    , atView: View? = null // 依附于那个View显示
    , watchView: View? = null // 依附于那个View显示
    // 动画执行器，如果不指定，则会根据窗体类型popupType字段生成默认合适的动画执行器
    , popupAnimation: PopupAnimation? = null, customAnimator: PopupAnimator? = null, touchPoint: PointF? = null // 触摸的点
    , maxWidth: Int = 0 // 最大宽度
    , maxHeight: Int = 0 // 最大高度
    , autoOpenSoftInput: Boolean? = false //是否自动打开输入法
    , xPopupCallback: XPopupCallback? = null, decorView: ViewGroup? = null//每个弹窗所属的DecorView
    , isMoveUpToKeyboard: Boolean? = true //是否移动到软键盘上面，默认弹窗会移到软键盘上面
    , popupPosition: PopupPosition? = null //弹窗出现在目标的什么位置
    , hasStatusBarShadow: Boolean? = false //是否显示状态栏阴影
    , hasStatusBar: Boolean? = true //是否显示状态栏
    , hasNavigationBar: Boolean? = true //是否显示导航栏
    , offsetX: Int = 0, offsetY: Int = 0 //x，y方向的偏移量
    , enableDrag: Boolean? = true //是否启用拖拽
    , isCenterHorizontal: Boolean = false //是否水平居中
    , isRequestFocus: Boolean = true //弹窗是否强制抢占焦点
    , autoFocusEditText: Boolean = true //是否让输入框自动获取焦点
    , isClickThrough: Boolean = false //是否点击透传，默认弹背景点击是拦截的
    , isDarkTheme: Boolean = false //是否是暗色调主题
    , enableShowWhenAppBackground: Boolean = false //是否允许应用在后台的时候也能弹出弹窗
    , isThreeDrag: Boolean = false //是否开启三阶拖拽
    , isDestroyOnDismiss: Boolean = false //是否关闭后进行资源释放
    , isInQueue: Boolean = false  //是否在队列里面
) = this.apply {

    val popupType = when (this) {
        is CenterPopupView -> PopupType.Center
        is BottomPopupView -> PopupType.Bottom
        is AttachPopupView -> PopupType.AttachView
        is ImageViewerPopupView -> PopupType.ImageViewer
        is PositionPopupView -> PopupType.Position
        else -> PopupType.Center
    }
    this.popupInfo = PopupInfo().also { info ->
        info.popupType = popupType
        info.isDismissOnBackPressed = isDismissOnBackPressed
        info.isDismissOnTouchOutside = isDismissOnTouchOutside
        info.autoDismiss = autoDismiss
        info.hasShadowBg = hasShadowBg
        info.hasBlurBg = hasBlurBg
        info.atView = atView
        info.watchView = watchView
        info.popupAnimation = popupAnimation
        info.customAnimator = customAnimator
        info.touchPoint = touchPoint
        info.maxWidth = maxWidth
        info.maxHeight = maxHeight
        info.autoOpenSoftInput = autoOpenSoftInput
        info.xPopupCallback = xPopupCallback
        info.decorView = decorView
        info.isMoveUpToKeyboard = isMoveUpToKeyboard
        info.popupPosition = popupPosition
        info.hasStatusBarShadow = hasStatusBarShadow
        info.hasStatusBar = hasStatusBar
        info.hasNavigationBar = hasNavigationBar
        info.offsetX = offsetX
        info.offsetY = offsetY
        info.enableDrag = enableDrag
        info.isCenterHorizontal = isCenterHorizontal
        info.isRequestFocus = isRequestFocus
        info.autoFocusEditText = autoFocusEditText
        info.isClickThrough = isClickThrough
        info.isDarkTheme = isDarkTheme
        info.enableShowWhenAppBackground = enableShowWhenAppBackground
        info.isThreeDrag = isThreeDrag
        info.isDestroyOnDismiss = isDestroyOnDismiss
    }
}

/**获取下次弹窗展示前执行操作，返回延迟时间*/
typealias BeforeNextDialogShow = () -> Long

///弹窗，和获取
private val queue = ConcurrentLinkedQueue<Pair<BasePopupView?, BeforeNextDialogShow?>>() //弹窗队列(线程安全)
private var mPopUp: BasePopupView? = null

fun <T : BasePopupView> T.showInQueue(block: BeforeNextDialogShow? = null) {
    val originXPopupCallback = popupInfo.xPopupCallback
    queue.add(this to block)
    val lXPopupCallback = object : XPopupCallback {
        override fun onCreated(popupView: BasePopupView?) {
            originXPopupCallback?.onCreated(popupView)
        }

        override fun beforeShow(popupView: BasePopupView?) {
            originXPopupCallback?.beforeShow(popupView)
        }

        override fun onShow(popupView: BasePopupView?) {
            originXPopupCallback?.onShow(popupView)
        }

        override fun onDismiss(popupView: BasePopupView?) {
            originXPopupCallback?.onDismiss(popupView)
            queue.poll()
            startNextIfCan()
        }


        override fun beforeDismiss(popupView: BasePopupView?) {
            originXPopupCallback?.beforeDismiss(popupView)
        }

        override fun onBackPressed(popupView: BasePopupView?): Boolean {
            return originXPopupCallback?.onBackPressed(popupView) ?: false
        }
    }
    popupInfo.xPopupCallback = lXPopupCallback
    if (!canShow()) return
    startNextIfCan()
}

///下一个任务是否可以展示，小于两个就能展示，多的话说明之前的还没有取消
private fun canShow() = queue.size < 2

///弹出一个弹窗
private fun startNextIfCan() {
    if (queue.isEmpty()) return
    val element = queue.element() ?: return
    mPopUp = element.first
    MainScope().launch {
        delay(element.second?.invoke() ?: 0)
        mPopUp?.show()
    }
}